package ink.chow.jdbc.sharding.conf;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import io.shardingjdbc.core.api.ShardingDataSourceFactory;
import io.shardingjdbc.core.api.config.ShardingRuleConfiguration;
import io.shardingjdbc.core.api.config.TableRuleConfiguration;
import io.shardingjdbc.core.api.config.strategy.StandardShardingStrategyConfiguration;
import io.shardingjdbc.core.util.DataSourceUtil;


@Configuration
public class DataSourceConfig {
	@Autowired
	private Environment env;
	
	
	public Map<String, DataSource> getDataSources(Map<String, Object> m) throws ReflectiveOperationException{
		Map<String, DataSource> result = new HashMap<>();
		result.put("ds", DataSourceUtil.getDataSource(DruidDataSource.class.getName(), m));
		return result;
	}
	
	@Bean
	@Primary
	public DataSource getShardingDataSource(@Autowired @Qualifier("druid") Map<String, Object> druid) throws SQLException, ReflectiveOperationException {
		ShardingRuleConfiguration configuration = new ShardingRuleConfiguration();
		configuration.getTableRuleConfigs().add(geTableRuleConfiguration());
		configuration.getBindingTableGroups().add("customer_track");
		configuration.setDefaultTableShardingStrategyConfig(new StandardShardingStrategyConfiguration("id", StringModShardingAlgorithm.class.getName()));
		return ShardingDataSourceFactory.createDataSource(getDataSources((Map<String, Object>) druid.get("druid")), configuration, new HashMap<>(), null);
	}
	
	private TableRuleConfiguration geTableRuleConfiguration() {
		TableRuleConfiguration configuration = new TableRuleConfiguration();
		configuration.setLogicTable("customer_track");
		configuration.setActualDataNodes("ds.customer_track_${0..1}");
		return configuration;
	}
	
	@Bean("druid")
	@ConfigurationProperties("spring.datasource.druid")
	public Map<String, Object> getProperties(){
		return new HashMap<>();
	}
}
